#include <iostream>
#include "fooking.h"
#include "Router.h"
#include "Master.h"
#include "Config.h"
#include "Log.h"

NS_USING;

extern char **environ;

static void daemonize()
{
	if (fork() != 0){
		exit(0); /* parent exit */
	}

	setsid();

	int fd;
	if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
		dup2(fd, STDIN_FILENO);
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);
		if (fd > STDERR_FILENO) close(fd);
	}
}

static void initProcTitle()
{
	size_t size = 0;
	for (int i = 0; environ[i]; ++i) {
		size += strlen(environ[i]) + 1; 
	}

	char *raw = new char[size];
	for(int i = 0; environ[i]; ++i) {
		int envlen = strlen(environ[i]) + 1;
		memcpy(raw, environ[i], envlen);
		environ[i] = raw;
		raw+= envlen;
	}
}


int main(int argc, char **argv)
{
	//args check
	if(argc < 2){
		printf("usage: fooking config.lua\n");
		return -1;
	}
	
	//init config
	Config *pConfig = Config::getInstance();
	if(!pConfig->load(argv[1])){
		return -1;
	}
	
	//int log
	Log *pLog = Log::getInstance();
	if(pConfig->sLogFile == "stdout"){
		pLog->init(pConfig->nLogLevel, STDOUT_FILENO);
	}else if(pConfig->sLogFile == "stderr"){
		pLog->init(pConfig->nLogLevel, STDERR_FILENO);
	}else if(!pConfig->sLogFile.empty() && 
		!pLog->init(pConfig->nLogLevel, pConfig->sLogFile.c_str()))
	{
		printf("init log failed\n");
		return -1;
	}
	
	//daemonize
	if(pConfig->bDaemonize){
		daemonize();
	}
	
	//title init
	initProcTitle();
	
	//server
	if(pConfig->bRouter){
		//router server
		Router *pRouter = new Router(argc, argv);
		pRouter->start();
	}else{
		//gateway server
		Master *pMaster = new Master(argc, argv);
		pMaster->start();
	}
	
	return 0;
}